DATGEN BREAK	EQU	2		;BREAK KEY BIT
 CLS	EQU	1C9H		;CLEAR SCREEN
 CPHLDE	EQU	1C90H		;COMPARE HL AND DE
 DATA	EQU	88H		;BASIC TOKEN FOR DATA
 DGT	EQU	1		;DIGIT FLAG ON
 END	EQU	40F9H		;PTR TO BASIC PROGRAM END
 FIXPTR	EQU	1AF8H		;CALCULATE LINE POINTERS
 GETDGT	EQU	1D78H		;SET C FOR NUMERIC CHAR
 INIT	EQU	1AEFH		;RETURN TO BASIC
 INPSTR	EQU	1BB3H		;INPUT STRING FROM KB
 LENGTH	EQU	10		;BYTES PER BASIC LINE
 NODGT	EQU	0		;DIGIT FLAG OFF
 OUTSTR	EQU	28A7H		;DISPLAY STRING
 ROW7	EQU	3840H		;BREAK KEY ROW
 	ORG	7E00H		;32256 DECIMAL
 DATGEN	CALL	CLS		;CLEAR SCREEN
 	LD	HL,PRMPT1	;POINT TO FIRST PROMPT
 	CALL	GETINT		;INPUT FIRST ADDRESS
 	LD	(MACH),HL	;STORE IT
 	LD	HL,PRMPT2	;POINT TO SECOND PROMPT
 	CALL	GETINT		;INPUT LAST ADDRESS
 	LD	(LAST),HL	;STORE IT
 	LD	HL,PRMPT3	;POINT TO THIRD PROMPT
 	CALL	GETINT		;INPUT FIRST BASIC LINE#
 	LD	(LINE),HL	;STORE IT
 	LD	HL,PRMPT4	;POINT TO FOURTH PROMPT
 	CALL	GETINT		;INPUT INCREMENT
 	LD	(INC),HL	;STORE IT
 	LD	IX,(END)	;2+ADDR OF PROGRAM END
 	DEC	IX		;CORRECT IX TO POINT
 	DEC	IX		;TO END OF PROGRAM
 NEWLIN	LD	A,0FFH		;ANYTHING > 0
 	CALL	PUTCHR		;FILL LINE POINTER
 	CALL	PUTCHR		;TEMPORARILY
 	LD	HL,(LINE)	;BASIC LINE#
 	LD	A,L		;LINE# LSB
 	CALL	PUTCHR		;ADD TO PROGRAM
 	LD	A,H		;LINE# MSB
 	CALL	PUTCHR		;ADD TO PROGRAM
 	LD	A,DATA		;DATA TOKEN
 	CALL	PUTCHR		;ADD TO PROGRAM
 	CALL	PUTSPC		;ADD SPACE TO PROGRAM
 	LD	A,LENGTH	;BYTES PER LINE
 	LD	(BYTE),A	;STORE IT
 NEWBYT	LD	HL,(MACH)	;ADDRESS OF MACHINE BYTE
 	LD	B,(HL)		;MACHINE BYTE
 	LD	C,NODGT		;NO DIGITS YET
 	LD	D,100		;HUNDRED'S DIGIT
 	CALL	DIGIT		;ADD ASCII TO PROGRAM
 	LD	D,10		;TEN'S DIGIT
 	CALL	DIGIT		;ADD ASCII TO PROGRAM
 	LD	C,DGT		;PUT DIGIT, NOT SPACE
 	LD	D,1		;UNIT'S DIGIT
 	CALL	DIGIT		;ADD ASCII TO PROGRAM
 	LD	DE,(LAST)	;ADDRESS OF LAST BYTE
 	CALL	CPHLDE		;COMPARE WITH MACH ADDR
 	JR	NC,DONE		;JUMP IF LAST BYTE DONE
 	INC	HL		;POINT TO NEXT BYTE
 	LD	(MACH),HL	;STORE IT
 	LD	HL,BYTE		;BYTES LEFT IN LINE
 	DEC	(HL)		;ONE LESS
 	JR	Z,FINLIN	;JUMP IF LINE DONE
 	LD	A,','		;SEPARATE DATA
 	CALL	PUTCHR		;ADD TO PROGRAM
 	JR	NEWBYT		;DO NEXT MACHINE BYTE
 FINLIN	XOR	A		;END OF LINE
 	CALL	PUTCHR		;ADD TO PROGRAM
 	LD	HL,(LINE)	;LINE#
 	LD	BC,(INC)	;INCREMENT
 	ADD	HL,BC		;NEXT LINE#
 	LD	(LINE),HL	;STORE IT
 	JR	NEWLIN		;DO NEXT LINE
 DONE	XOR	A		;ZERO
 	LD	B,3		;THREE OF THEM
 OUTZER	CALL	PUTCHR		;ADD TO PROGRAM
 	DJNZ	OUTZER		;THREE "0"'S
 	LD	(END),IX	;STORE PROGRAM END PTR
 	CALL	FIXPTR		;CALCULATE LINE POINTERS
 	JP	INIT		;RETURN TO BASIC
 GETINT	PUSH	HL		;SAVE PROMPT ADDRESS
 	POP	IX		;IN IX
 MESS	PUSH	IX		;RESTORE PROMPT ADDRESS
 	POP	HL		;TO HL
 	CALL	OUTSTR		;DISPLAY PROMPT
 	CALL	INPSTR		;INPUT STRING
 	LD	A,(ROW7)	;BREAK KEY ROW
 	BIT	BREAK,A		;BREAK KEY PRESSED?
 	JR	Z,NOBRK		;JUMP IF NOT
 	POP	HL		;FIX STACK
 	JP	DATGEN		;START OVER
 NOBRK	LD	DE,0		;INTEGER=0
 	CALL	GETDGT		;GET NEXT CHAR FROM INPUT
 	JR	C,DEC		;IF DIGIT, BASE 10
 	JR	Z,FINISH	;IF CR, RETURN 0
 	CP	'H'		;IS IT H(EX)?
 	JR	NZ,MESS		;NO, PROMPT AGAIN
 	CALL	GETDGT		;GET HEX DIGIT
 HEX	JR	C,NUMBER	;JUMP IF 0-9
 	JR	Z,FINISH	;RETURN IF CR
 	CP	'A'		;LESS THAN "A"?
 	JR	C,MESS		;PROMPT AGAIN IF IT IS
 	CP	'F'+1		;GREATER THAN "F"?
 	JR	NC,MESS		;PROMPT AGAIN IF IT IS
 	SUB	7		;CONVERT A-F
 NUMBER	PUSH	HL		;SAVE INPUT BUFFER PTR
 	POP	IY		;IN IY
 	EX	DE,HL		;HL IS INTEGER
 	ADD	HL,HL		;MULTIPLY
 	ADD	HL,HL		;INTEGER
 	ADD	HL,HL		;BY
 	ADD	HL,HL		;10H
 	CALL	ADDCHR		;ADD CHAR TO INTEGER
 	JR	HEX		;LOOK AT NEXT CHARACTER
 DEC	PUSH	HL		;SAVE INPUT BUFFER PTR
 	POP	IY		;IN IY
 	LD	H,D		;COPY INTEGER
 	LD	L,E		;TO HL
 	ADD	HL,DE		;MULTIPLY
 	ADD	HL,HL		;INTEGER
 	ADD	HL,DE		;BY
 	ADD	HL,HL		;10
 	CALL	ADDCHR		;ADD CHAR TO INTEGER
 	JR	C,DEC		;JUMP IF 0-9
 	JR	NZ,MESS		;PROMPT AGAIN IF NOT CR
 FINISH	EX	DE,HL		;MOVE INTEGER TO HL
 	RET			;RETURN
 ADDCHR	SUB	'0'		;CONVERT TO HEX
 	LD	D,0		;ZERO MSB
 	LD	E,A		;LSB=CHAR
 	ADD	HL,DE		;ADD CHAR
 	EX	DE,HL		;RESTORE INTEGER TO DE
 	PUSH	IY		;RESTORE INPUT BUFFER PTR
 	POP	HL		;TO HL
 	JP	GETDGT		;GET NEXT CHAR AND RETURN
 DIGIT	LD	A,B		;MACHINE BYTE REMAINDER
 	LD	E,'0'-1		;ASCII OF DIGIT
 DIV	INC	E		;NEXT DIGIT
 	SUB	D		;DECREMENT PLACE VALUE
 	JR	NC,DIV		;AGAIN IF NOT NEGATIVE
 	ADD	A,D		;UNDO EXTRA SUBTRACTION
 	LD	B,A		;SAVE REMAINDER
 	BIT	0,C		;CHECK TO SEE IF DIGIT
 	JR	NZ,NOSKIP	;ADD DIGIT IF C IS 1
 	LD	A,'0'		;ASCII 0
 	CP	E		;COMPARE WITH DIGIT
 	JR	NZ,NOSPC	;ADD DIGIT IF NONZERO
 PUTSPC	LD	A,' '		;LEFT JUSTIFY WITH SPACE
 	JR	PUTCHR		;ADD IT TO PROGRAM
 NOSPC	LD	C,DGT		;SET DIGIT FLAG
 NOSKIP	LD	A,E		;CHAR
 PUTCHR	LD	(IX+0),A	;PUT A IN BASIC PROGRAM
 	INC	IX		;POINT TO NEXT BYTE
 	RET			;RETURN
 PRMPT1	DEFM	'FIRST ADDRESS'	;FIRST PROMPT
 	DEFB	0		;END OF STRING
 PRMPT2	DEFM	'LAST ADDRESS'	;SECOND PROMPT
 	DEFB	0		;END OF STRING
 PRMPT3	DEFM	'FIRST LINE'	;THIRD PROMPT
 	DEFB	0		;END OF STRING
 PRMPT4	DEFM	'INCREMENT'	;FOURTH PROMPT
 	DEFB	0		;END OF STRING
 BYTE	DEFS	1		;BYTES LEFT IN LINE
 INC	DEFS	2		;LINE# INCREMENT
 LAST	DEFS	2		;ADDR OF LAST MACH BYTE
 LINE	DEFS	2		;CURRENT LINE#
 MACH	DEFS	2		;CURRENT MACH BYTE ADDR
 	END	DATGEN		;FINIS
